/**
 * @class   wosh::persistence::libxml2::EncoderProtocolXmlL2
 * @brief   
 *
 *
 *
 *
 *
 * \verbatim
apt-get install 
\endverbatim
 *
 *
 *
 *
 ****************************************************************************
 * @version 0.8.399 $Id: EncoderProtocolXmlL2.h 2542 2010-05-26 00:48:23Z alex $
 * @author  Alessandro Polo
 ****************************************************************************/
/* Copyright (c) 2007-2010, WOSH - Wide Open Smart Home 
 * by Alessandro Polo - OpenSmartHome.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the OpenSmartHome.com WOSH nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY Alessandro Polo ''AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL Alessandro Polo BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ****************************************************************************/

#ifndef __WOSH_Persistence_libxml2_EncoderProtocolXmlL2_H__
 #define __WOSH_Persistence_libxml2_EncoderProtocolXmlL2_H__

 #include <framework/persistence/EncoderProtocolXml.h>
 #include <core/ObjectFactory.h>

 #include <libxml/tree.h>


using namespace wosh;
namespace wosh {
 class PersistenceDb;
 namespace persistence {
  namespace libxml2 {




#undef WOSH_ENCODER_XML_L2_CLASS
#define WOSH_ENCODER_XML_L2_CLASS(CLASSNAME, OBJECT_TYPE)		\
	class CLASSNAME : public wosh::persistence::libxml2::EncoderBaseXmlL2 {													\
		public: virtual inline bool isAbstract() const { return false; }													\
		public: static inline const char* className() { return "wosh::persistence::libxml2::" #CLASSNAME; }					\
		public: virtual inline const char* getClassName() const { return className(); }										\
		public: static inline const char* mappedObject() { return #OBJECT_TYPE; }											\
		public: virtual inline const char* getMappedObject() const { return mappedObject(); }								\
		public: inline WRESULT serializeTo( const ISerializable* object_s, xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr contNode, int encoder_options ) {	\
			return CLASSNAME::serializeTo( dynamic_cast<const OBJECT_TYPE*>(object_s), doc, ns, contNode, encoder_options); }							\
		public: inline WRESULT deserializeFrom( ISerializable* object_s, xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr contNode ) {					\
			return CLASSNAME::deserializeFrom( dynamic_cast<OBJECT_TYPE*>(object_s), doc, ns, contNode); }										\
		public: static WRESULT serializeTo( const OBJECT_TYPE* object, xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr contNode, int encoder_options );			\
		public: static WRESULT deserializeFrom( OBJECT_TYPE* object, xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr contNode );							\
		public: CLASSNAME() : EncoderBaseXmlL2() { }																		\
	};

#undef WOSH_ENCODER_XML_L2_BIND
#define WOSH_ENCODER_XML_L2_BIND(ENCODER_CLASS, OBJECT_CLASSNAME, VERSION, TMP ) \
	WOSH_ENCODER_BIND(wosh::persistence::libxml2::EncoderProtocolXmlL2, ENCODER_CLASS, OBJECT_CLASSNAME, VERSION, TMP )



class EncoderBaseXmlL2 : public EncoderBaseXml
 {
	WOSH_CLASSNAME(wosh::persistence::libxml2::EncoderBaseXmlL2)
	WOSH_CLASS_ABSTRACT(true)

	public:
		virtual WRESULT serializeTo( const ISerializable* object, xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr contNode, int encoder_options ) = 0;
		virtual WRESULT deserializeFrom( ISerializable* object, xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr contNode ) = 0;

	public:
		virtual int64 serializeTo( const ISerializable* object, char* buffer, int64 buffer_size, int encoder_options );
		virtual int64 deserializeFrom( ISerializable* object, const char* buffer, int64 buffer_size );

	public:
//		virtual int64 serializeTo( const ISerializable* object, const std::string& filename, int encoder_options );
//		virtual WRESULT deserializeFrom( ISerializable* object, const std::string& filename );


	public:
		static void serializeString( const std::string& field, const std::string& value, xmlNodePtr contNode, int encoder_options );

	public:
		static std::string deserializeString( const std::string& field, const std::string& default_value, xmlNodePtr contNode, bool* valid = NULL );


	public:
		template <class ObjectType, class EncoderType>
		static WRESULT serializeListT( const typename wosh::ListT<ObjectType*>& dataset, xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr contNode, int encoder_options ) {
			WRESULT ret = WRET_OK;
			EncoderType encoder;
			dataset.transactionBeginRead();
		//	EncoderBaseXmlL2::serializeLong( "size", dataset.size(), doc, contNode, true );
			typename wosh::ListT<ObjectType*>::ConstIterator it;
			const typename wosh::ListT<ObjectType*>::ConstIterator it_end = dataset.end();
			for ( it=dataset.begin(); it!=it_end; ++it ) {
	//			QDomElement itemNode = doc.createElement("item"); contNode.appendChild(itemNode);
	//			if ( *it == NULL ) continue;
	//			ret += encoder.serializeTo( *it, doc, itemNode, encoder_options );
			 }
			dataset.transactionEnd();
			return ret;
		 }

		template <class ObjectType, class EncoderType>
		static WRESULT deserializeListT( typename wosh::ListT<ObjectType*>& dataset, const xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr contNode ) {
			WRESULT ret = WRET_OK; WRESULT ret_t = WRET_OK;
			EncoderType encoder;
			dataset.transactionBeginWrite();
	/*		QDomNodeList nodesList = contNode.childNodes();
			for( unsigned int j=0; j<nodesList.length(); ++j ) {
				QDomElement childNode = nodesList.item(j).toElement();
				ObjectType* object = ObjectFactory::createTypeOf<ObjectType>();
				if ( object == NULL ) {
					dataset.push_back(NULL);
					continue;
				 }
				ret_t = encoder.deserializeFrom( object, childNode );
				if ( WSUCCEEDED(ret_t) )
					dataset.push_back(object);
				else {
					dataset.push_back(NULL);
					ret += WRET_ERR_PARAM;
				 }
			 }
	*/		dataset.transactionEnd();
			return ret;
		 }

	public:
		EncoderBaseXmlL2() : EncoderBaseXml() { }
		virtual ~EncoderBaseXmlL2() { }

};


// ------------------------------------------------------------------------------------------------------------------------


class PersistenceDbXmlL2;

class EncoderProtocolXmlL2 : public EncoderProtocolXml
 {
	WOSH_ENCODERPROTOCOL(wosh::persistence::libxml2::EncoderProtocolXmlL2)

	public:
		EncoderProtocolXmlL2();
		virtual ~EncoderProtocolXmlL2();

	public:
		const char* getProtocol() const		{ return "XML::LIBXML2"; }
		double getProtocolVersion() const	{ return 0.0; }

		PersistenceDb* createDb() const;


	public:
	//	virtual WRESULT loadObjects( ISerializable* objects, const std::string& class_name, const std::string& archive_name ) = 0;
		WRESULT loadObjects( std::vector<ISerializable*>& objects, const std::string& parameters );

		WRESULT saveObject( const ISerializable* object, const std::string& parameters );
		WRESULT saveObjects( const std::vector<ISerializable*>& objects, const std::string& parameters );

	public:
		static int64 serializeTo( const ISerializable* object, xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr contNode, int encoder_options );
		static int64 deserializeFrom( ISerializable* object, xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr contNode );
		static ISerializable* deserializeFrom( xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr contNode, WRESULT* return_code = NULL );

		template <class DYNAMIC_CAST>
		static inline DYNAMIC_CAST* deserializeFrom( xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr contNode, WRESULT* return_code = NULL ) {
			return dynamic_cast<DYNAMIC_CAST*>( deserializeFrom(doc, ns, contNode, return_code) );
		 }

	protected:
//		WRESULT loadXmlDocument( QDomDocument& doc, const std::string& filename );
//		WRESULT saveXmlDocument( QDomDocument& doc, const std::string& filename );


}; // class def



  }; // namespace libxml2
 }; // namespace persistence
}; // namespace wosh

#endif //__WOSH_Persistence_libxml2_EncoderProtocolXmlL2_H__
